#include <p30f3013.h>
#include "type.h"
#include <spi.h>
#include "spi_osc.h"
#include "debug_led.h"

/* Define */
#define SS1 _LATB2
#define SS2 _LATB8

#define SS1_DDR _TRISB2
#define SS2_DDR _TRISB8

// Data sent to oscillators
#define CTRL_REG        0x2100

//Osc 1
#define FREQ0_LSB_OSC1   0x5783  
#define FREQ0_MSB_OSC1   0x414E

#define FREQ1_LSB_OSC1   0x9783
#define FREQ1_MSB_OSC1   0x814E

//Osc 2
#define FREQ0_LSB_OSC2   0x4925//0x4925
#define FREQ0_MSB_OSC2   0x4249//0x4249

#define FREQ1_LSB_OSC2   0x8925
#define FREQ1_MSB_OSC2   0x8249

// General
#define PHASE0          0xC000 // Zero phase
#define PHASE1			0xE000 // Zero phase

#define EXIT_RESET      0x2000


/* Function Prototypes */
void ss1_select();
void ss1_deselect();
void ss2_select();
void ss2_deselect();

void __attribute__((__interrupt__)) _SPIInterrupt(void);


/*****************************************************************************
** Function name:		spi_init
**
** Descriptions:		Initalise SPI Port for Oscillators
**
** parameters:		None
** Returned value:		None
**
*****************************************************************************/
 void spi_init(){
    uint16_t config1;
    uint16_t config2;

    // Set DDR to output (0)
    SS1_DDR = 0;
    SS2_DDR = 0;
    // Make sure they do not select a slave (logic is inverted)
    SS1 = 1;
    SS2 = 1;

    config1 =   FRAME_ENABLE_OFF &
                FRAME_SYNC_OUTPUT &
                ENABLE_SDO_PIN &
                SPI_MODE16_ON &
                SPI_CKE_ON &
                SLAVE_ENABLE_OFF & // Will manually do this
                CLK_POL_ACTIVE_LOW &
                MASTER_ENABLE_ON &
                SEC_PRESCAL_4_1 &
                PRI_PRESCAL_4_1;
                
	    config2 = 0x8000;  // SPI_ENABLE

        //Clear the SPI interrupt flag bit
        _SPI1IF = 0;

        _SPI1IP = 7; // Highest priority interrupt

        //Set the SPI interrupt enable bit
        _SPI1IE = 0;  // Interrputs disabled.

    OpenSPI1(config1, config2);
}
 
/*****************************************************************************
** Function name:		spi_set_osc1
**
** Descriptions:		Program Oscillator 1 to frequency 40 (kHz)
**
**                      Control data calculated from:
**                      http://designtools.analog.com/dt/ad98334/ad9833.html
**
**                      Generated frequency for 40 kHz with 1.96MHz clock:
**                      2100 5783 414E 9783 814E C000 E000 2000
**
** parameters:			freq - frequency of oscillator
** Returned value:		None
**
*****************************************************************************/
 void spi_set_osc1(){

        // make sure only writing data to osc1
        ss2_deselect(); // make sure only writing data to osc1
        // Start
      	
		led_yellow_on();
        // Send data to oscillator
		ss1_select();
        WriteSPI1(CTRL_REG);
		ss1_deselect();
		led_yellow_off();

	    led_yellow_on();
		ss1_select();
        WriteSPI1(FREQ0_LSB_OSC1);
		ss1_deselect();
		led_yellow_off();
	
		led_yellow_on();
		ss1_select();
        WriteSPI1(FREQ0_MSB_OSC1);
		ss1_deselect();

		led_yellow_on();
		ss1_select();
		WriteSPI1(FREQ1_LSB_OSC1);
		ss1_deselect();
	    led_yellow_off();
		
		led_yellow_on();
		ss1_select();
        WriteSPI1(FREQ1_MSB_OSC1);
		ss1_deselect();
        led_yellow_off();

		led_yellow_on();
		ss1_select();
        WriteSPI1(PHASE0);
		ss1_deselect();
        led_yellow_off();

		led_yellow_on();
		ss1_select();
        WriteSPI1(PHASE1);
		ss1_deselect();
		led_yellow_off();

		led_yellow_on();
		ss1_select();
        WriteSPI1(EXIT_RESET);
     	ss1_deselect();   
		led_yellow_off();  
        // Stop
}
 
 /*****************************************************************************
** Function name:		spi_set_osc2
**
** Descriptions:		Program Oscillator 2 to frequency 70 (kHz)
**
**                      Control data calculated from:
**                      http://designtools.analog.com/dt/ad98334/ad9833.html
**
**                      Generated frequency for 70 kHz with 1.96MHz clock:
**                      2100 4925 4249 8925 8249 C000 E000 2000
**
** parameters:			freq - frequency of oscillator
** Returned value:		None
**
*****************************************************************************/
 void spi_set_osc2(){
        // make sure only writing data to osc1
        ss1_deselect(); // make sure only writing data to osc1
        
		// Start
        // Send data to oscillator
		ss2_select();
        WriteSPI1(CTRL_REG);
		ss2_deselect();
	//	led_yellow_off();

		ss2_select();
        WriteSPI1(FREQ0_LSB_OSC2);
		ss2_deselect();
		
	//	led_yellow_on();
		ss2_select();
        WriteSPI1(FREQ0_MSB_OSC2);
		ss2_deselect();
		
		ss2_select();
		WriteSPI1(FREQ1_LSB_OSC2);
		ss2_deselect();
		
	//	led_yellow_on();
		ss2_select();
        WriteSPI1(FREQ1_MSB_OSC2);
		ss2_deselect();

	//	led_yellow_off();
		ss2_select();
        WriteSPI1(PHASE0);
		ss2_deselect();

		ss2_select();
        WriteSPI1(PHASE1);
		ss2_deselect();

	//	led_yellow_on();
		ss2_select();
        WriteSPI1(EXIT_RESET);
       	ss2_deselect(); 
    
       // Stop

}

 /*****************************************************************************
** Function name:		spi_close
**
** Descriptions:		Program Oscillator 2 to frequency (kHz)
**
** parameters:			freq - frequency of oscillator
** Returned value:		None
**
*****************************************************************************/
 void spi_close(){
	CloseSPI1();
}

 /*****************************************************************************
** Function name:		ss1_on
**
** Descriptions:		Select spi slave osc1
**
** parameters:			freq - frequency of oscillator
** Returned value:		None
**
*****************************************************************************/
void ss1_select(){
    SS1 = 0;
}

 /*****************************************************************************
** Function name:		ss2_on
**
** Descriptions:		Select spi slave osc2
**
** parameters:			None
** Returned value:		None
**
*****************************************************************************/
void ss2_select(){
    SS2 = 0;
}

 /*****************************************************************************
** Function name:		ss1_off
**
** Descriptions:		Deselect spi slave osc1
**
** parameters:			None
** Returned value:		None
**
*****************************************************************************/
void ss1_deselect(){

    // Wait for SPI to send data
	int i =0;
	for(i= 0;i<50;i++){
		continue;
	}	
	i=3;
	i=2;


    SS1 = 1;
}
 /*****************************************************************************
** Function name:		ss2_off
**
** Descriptions:		Deselect spi slave osc2
**
** parameters:			None
** Returned value:		None
**
*****************************************************************************/
void ss2_deselect(){

    // Wait for SPI to send data
	int i =0;
	for(i= 0;i<50;i++){
		continue;
	}	
	i=3;
	i=2;

    SS2 = 1;
}

/*****************************************************************************
** Function name:		_ISR _SPIInterrupt
**
** Descriptions:		ADC Interrupt Vector
**
** Parameters:		    None
** Returned value:		None
**
*****************************************************************************/
void _ISR _SPIInterrupt(void){

    //led_green_on(); //   GREEN_LED = 1;
    SS1 = 1;
    SS2 = 1;
   // led_green_off();//  GREEN_LED = 0;

    IFS0bits.SPI1IF = 0;
}
